home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Online / opennap / change.c < prev    next >
C/C++ Source or Header  |  2001-06-08  |  11KB  |  475 lines

  1. /* Copyright (C) 2000-1 drscholl@users.sourceforge.net
  2.    This is free software distributed under the terms of the
  3.    GNU Public License.  See the file COPYING for details.
  4.  
  5.    $Id: change.c,v 1.65 2001/02/15 08:39:45 drscholl Exp $ */
  6.  
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "opennap.h"
  10. #include "debug.h"
  11.  
  12. /* user request to change the data port they are listening on.
  13.    703 [ :<user> ] <port> */
  14. HANDLER (change_data_port)
  15. {
  16.     int     port;
  17.     USER   *user;
  18.  
  19.     (void) tag;
  20.     (void) len;
  21.     ASSERT (validate_connection (con));
  22.     if (pop_user (con, &pkt, &user) != 0)
  23.     return;
  24.     ASSERT (validate_user (user));
  25.     port = atoi (pkt);
  26.  
  27.     /* the official server doesn't seem to check the value sent, so this
  28.        error is unique to this implementation */
  29.     if (port >= 0 && port <= 65535)
  30.     {
  31.     user->port = port;
  32.     pass_message_args (con, tag, ":%s %hu", user->nick, user->port);
  33.     }
  34.     else if (ISUSER (con))
  35.     send_cmd (con, MSG_SERVER_NOSUCH, "invalid data port");
  36. }
  37.  
  38. /* 700 [ :<user> ] <speed> */
  39. /* client is changing link speed */
  40. HANDLER (change_speed)
  41. {
  42.     USER   *user;
  43.     int     spd;
  44.  
  45.     (void) tag;
  46.     (void) len;
  47.     ASSERT (validate_connection (con));
  48.     if (pop_user (con, &pkt, &user) != 0)
  49.     return;
  50.     spd = atoi (pkt);
  51.     if (spd >= 0 && spd <= 10)
  52.     {
  53.     user->speed = spd;
  54.     pass_message_args (con, tag, ":%s %d", user->nick, spd);
  55.     }
  56.     else if (ISUSER (con))
  57.     send_cmd (con, MSG_SERVER_NOSUCH, "invalid speed");
  58. }
  59.  
  60. /* 701 [ :<user> ] <password>
  61.    change user password */
  62. HANDLER (change_pass)
  63. {
  64.     USER   *user;
  65.     USERDB *db;
  66.  
  67.     (void) tag;
  68.     (void) len;
  69.     if (pop_user (con, &pkt, &user) != 0)
  70.     return;
  71.     if (!pkt || !*pkt)
  72.     {
  73.     log ("change_pass(): missing new password");
  74.     unparsable (con);
  75.     return;
  76.     }
  77.     /* pass this along even if it is not locally registered.  the user db
  78.      * is distributed so a record for it may reside on another server */
  79.     pass_message_args (con, tag, ":%s %s", user->nick, pkt);
  80.     db = hash_lookup (User_Db, user->nick);
  81.     if (!db)
  82.     {
  83.     log ("change_pass(): %s is not registered", user->nick);
  84.     return;
  85.     }
  86.     FREE (db->password);
  87.     db->password = generate_pass (pkt);
  88.     if (ISUSER (con))
  89.     send_cmd (con, MSG_SERVER_NOSUCH, "password changed");
  90. }
  91.  
  92. /* 702 [ :<user> ] <email>
  93.    change email address */
  94. HANDLER (change_email)
  95. {
  96. #if EMAIL
  97.     USER   *user;
  98.     USERDB *db;
  99.  
  100.     (void) tag;
  101.     (void) len;
  102.     if (pop_user (con, &pkt, &user) != 0)
  103.     return;
  104.     if (!pkt || !*pkt)
  105.     {
  106.     log ("change_email(): missing new email address");
  107.     unparsable (con);
  108.     return;
  109.     }
  110.     pass_message_args (con, tag, ":%s %s", user->nick, pkt);
  111.     db = hash_lookup (User_Db, user->nick);
  112.     if (!db)
  113.     {
  114.     log ("change_email(): could not find user %s in the database",
  115.          user->nick);
  116.     return;
  117.     }
  118.     FREE (db->email);
  119.     db->email = STRDUP (pkt);
  120. #else
  121.     (void) tag;
  122.     (void) len;
  123.     (void) pkt;
  124.     (void) con;
  125. #endif
  126. }
  127.  
  128. /* 613 [ :<sender> ] <user> <port> [ <reason> ]
  129.    admin request to change a user's data port */
  130. HANDLER (alter_port)
  131. {
  132.     USER   *sender, *user;
  133.     char   *nick, *port;
  134.     int     p;
  135.  
  136.     (void) tag;
  137.     (void) len;
  138.     ASSERT (validate_connection (con));
  139.     if (pop_user (con, &pkt, &sender) != 0)
  140.     return;
  141.     /* check for privilege */
  142.     if (sender->level < LEVEL_MODERATOR)
  143.     {
  144.     log ("alter_port(): %s has no privilege to change ports",
  145.          sender->nick);
  146.     permission_denied (con);
  147.     return;
  148.     }
  149.  
  150.     nick = next_arg (&pkt);
  151.     port = next_arg (&pkt);
  152.     if (!nick || !port)
  153.     {
  154.     unparsable (con);
  155.     return;
  156.     }
  157.     user = hash_lookup (Users, nick);
  158.     if (!user)
  159.     {
  160.     nosuchuser (con);
  161.     return;
  162.     }
  163.     p = atoi (port);
  164.     if (p < 0 || p > 65535)
  165.     {
  166.     if (ISUSER (con))
  167.         send_cmd (con, MSG_SERVER_NOSUCH, "%d is an invalid port", p);
  168.     return;
  169.     }
  170.  
  171.     if (pkt)
  172.     truncate_reason (pkt);
  173.  
  174.     if (user->port != p)
  175.     {
  176.     /* only log when the port value is actually changed, not resets */
  177.     notify_mods (CHANGELOG_MODE, "%s changed %s's data port to %d: %s",
  178.              sender->nick, user->nick, p, NONULL (pkt));
  179.     user->port = p;
  180.     }
  181.  
  182.     /* if local user, send them the message */
  183.     if (user->local)
  184.     send_cmd (user->con, MSG_CLIENT_ALTER_PORT, "%d", p);
  185.  
  186.     pass_message_args (con, tag, ":%s %s %d", sender->nick, user->nick, p);
  187.  
  188.     log ("alter_port: %s set %s's data port to %d", sender->nick,
  189.      user->nick, p);
  190. }
  191.  
  192. /* 753 [ :<sender> ] <nick> <pass> ["reason"]
  193.    admin command to change a user's password */
  194. HANDLER (alter_pass)
  195. {
  196.     USER   *sender;
  197.     int     ac = -1;
  198.     char   *av[3];
  199.     char   *sender_name;
  200.     USERDB *db;
  201.     USER    *target;
  202.  
  203.     ASSERT (validate_connection);
  204.     (void) tag;
  205.     (void) len;
  206.     if (pop_user_server (con, tag, &pkt, &sender_name, &sender))
  207.     return;
  208.     if (sender->level < LEVEL_ADMIN)
  209.     {
  210.     permission_denied (con);
  211.     return;
  212.     }
  213.     if (pkt)
  214.     ac = split_line (av, FIELDS (av), pkt);
  215.  
  216.     if (ac < 2)
  217.     {
  218.     log ("alter_pass(): wrong number of arguments");
  219.     print_args (ac, av);
  220.     unparsable (con);
  221.     return;
  222.     }
  223.     if (invalid_nick (av[0]))
  224.     {
  225.     if (ISUSER (con))
  226.         send_cmd (con, MSG_SERVER_NOSUCH,
  227.               "alter password failed: invalid nickname");
  228.     return;
  229.     }
  230.     target = hash_lookup (Users, av[0]);
  231.     if (target)
  232.     {
  233.     if (target->level >= sender->level)
  234.     {
  235.         send_cmd (con, MSG_SERVER_NOSUCH,
  236.             "alter password failed: permission denied");
  237.         return;
  238.     }
  239.     }
  240.  
  241.     if (ac > 2)
  242.     truncate_reason (av[2]);
  243.     /* send this now since the account might not be locally registered */
  244.     pass_message_args (con, tag, ":%s %s %s \"%s\"", sender->nick, av[0],
  245.                av[1], (ac > 2) ? av[2] : "");
  246.     db = hash_lookup (User_Db, av[0]);
  247.     if (db)
  248.     {
  249.     char   *newpass;
  250.  
  251.     if (db->level >= sender->level)
  252.     {
  253.         send_cmd (con, MSG_SERVER_NOSUCH,
  254.             "alter password failed: permission denied");
  255.         return;
  256.     }
  257.     newpass = generate_pass (av[1]);
  258.     if (!newpass)
  259.     {
  260.         OUTOFMEMORY ("alter_pass");
  261.         return;
  262.     }
  263.     FREE (db->password);
  264.     db->password = newpass;
  265.     }
  266.     notify_mods (CHANGELOG_MODE, "%s changed %s's password: %s",
  267.          sender->nick, av[0], (ac > 2) ? av[2] : "");
  268. }
  269.  
  270. /* 625 [ :<sender> ] <nick> <speed>
  271.    admin command to change another user's reported line speed */
  272. HANDLER (alter_speed)
  273. {
  274.     USER   *sender, *user;
  275.     int     ac, speed;
  276.     char   *av[2];
  277.  
  278.     ASSERT (validate_connection (con));
  279.     (void) len;
  280.     if (pop_user (con, &pkt, &sender))
  281.     return;
  282.     ac = split_line (av, sizeof (av) / sizeof (char *), pkt);
  283.  
  284.     if (ac < 2)
  285.     {
  286.     unparsable (con);
  287.     return;
  288.     }
  289.     if (sender->level < LEVEL_MODERATOR)
  290.     {
  291.     permission_denied (con);
  292.     return;
  293.     }
  294.     speed = atoi (av[1]);
  295.     if (speed < 0 || speed > 10)
  296.     {
  297.     if (ISUSER (con))
  298.         send_cmd (con, MSG_SERVER_NOSUCH, "Invalid speed");
  299.     return;
  300.     }
  301.     user = hash_lookup (Users, av[0]);
  302.     if (!user)
  303.     {
  304.     nosuchuser (con);
  305.     return;
  306.     }
  307.     ASSERT (validate_user (user));
  308.     if (user->speed == speed)
  309.     {
  310.     if (ISUSER (con))
  311.         send_cmd (con, MSG_SERVER_NOSUCH, "%s's speed is already %d",
  312.               user->nick, speed);
  313.     return;
  314.     }
  315.     user->speed = speed;
  316.     pass_message_args (con, tag, ":%s %s %d", sender->nick, user->nick,
  317.                speed);
  318.     notify_mods (CHANGELOG_MODE, "%s changed %s's speed to %d.", sender->nick,
  319.          user->nick, speed);
  320. }
  321.  
  322. /* 611 [ :<sender> ] <user> [ <reason> ]
  323.    nuke a user's account */
  324. HANDLER (nuke)
  325. {
  326.     USER   *sender, *user;
  327.     USERDB *db;
  328.     char   *nick, *sender_name;
  329.     int     level = -1;
  330.  
  331.     ASSERT (validate_connection (con));
  332.     (void) len;
  333.     if (pop_user_server (con, tag, &pkt, &sender_name, &sender))
  334.     return;
  335.     nick = next_arg (&pkt);
  336.     if (!nick)
  337.     {
  338.     if (ISUSER (con))
  339.         send_cmd (con, MSG_SERVER_NOSUCH,
  340.               "nuke failed: missing nickname");
  341.     else
  342.         log ("nuke: missing nick (from server %s)", con->host);
  343.     return;
  344.     }
  345.  
  346.     if (sender && sender->level < LEVEL_MODERATOR)
  347.     {
  348.     send_user (sender, MSG_SERVER_NOSUCH,
  349.         "[%s] nuke failed: permission denied", Server_Name);
  350.     return;
  351.     }
  352.  
  353.     db = hash_lookup (User_Db, nick);
  354.     user = hash_lookup (Users, nick);
  355.  
  356.     if (sender && sender->level < LEVEL_ELITE && (db || user))
  357.     {
  358.     level = user ? user->level : db->level;
  359.  
  360.     if (sender->level <= level &&
  361.         strcasecmp (sender->nick, db ? db->nick : user->nick) != 0)
  362.     {
  363.         send_user (sender, MSG_SERVER_NOSUCH,
  364.                "[%s] nuke failed: permission denied", Server_Name);
  365.         return;
  366.     }
  367.     }
  368.  
  369.     if (db)
  370.     hash_remove (User_Db, db->nick);
  371.  
  372.     if (pkt)
  373.     truncate_reason (pkt);
  374.  
  375.     /* if the user is currently logged in, set them to a sane state (one
  376.      * which would not require a db entry.
  377.      */
  378.     if (user)
  379.     {
  380.     user->level = LEVEL_USER;
  381.     if (user->cloaked)
  382.     {
  383.         if (ISUSER (user->con))
  384.         {
  385.         send_cmd (user->con, MSG_SERVER_NOSUCH,
  386.               "You are no longer cloaked.");
  387.         }
  388.         user->cloaked = 0;
  389.     }
  390.     user->muzzled = 0;
  391.     if (ISUSER (user->con))
  392.     {
  393.         send_cmd (user->con, MSG_SERVER_NOSUCH,
  394.               "%s nuked your account: %s",
  395.               sender && sender->cloaked ? "Operator" : sender_name,
  396.               NONULL (pkt));
  397.     }
  398.     }
  399.  
  400.     pass_message_args (con, tag, ":%s %s %s", sender_name, nick,
  401.                NONULL (pkt));
  402.  
  403.     notify_mods (CHANGELOG_MODE, "%s nuked %s's account: %s",
  404.          sender_name, nick, NONULL (pkt));
  405. }
  406.  
  407. /* 652 [ :<sender> ] [0 | 1]
  408.  * toggle the invisible state of the current user.  when a server is the
  409.  * sender of the message, the 1 signifies that the cloak status should
  410.  * absolutely be turned on rather than toggled (used for synch)
  411.  */
  412. HANDLER (cloak)
  413. {
  414.     USER   *sender;
  415.     int     bit = -1;
  416.     char   *sender_name;
  417.     char   *bitptr;
  418.  
  419.     (void) len;
  420.     ASSERT (validate_connection (con));
  421.     if (pop_user_server (con, tag, &pkt, &sender_name, &sender))
  422.     return;
  423.  
  424.     bitptr = next_arg (&pkt);
  425.  
  426.     if (bitptr)
  427.     {
  428.     bit = atoi (bitptr);
  429.     if (bit > 1 || bit < 0)
  430.     {
  431.         log ("cloak: invalid cloak state %s", bitptr);
  432.         if (ISUSER (con))
  433.         send_cmd (con, MSG_SERVER_NOSUCH,
  434.               "cloak failed: invalid cloak state %s", bitptr);
  435.         return;
  436.     }
  437.     }
  438.  
  439.     if (bit == -1)
  440.     bit = !sender->cloaked;    /* toggle */
  441.  
  442.     /* always allow the decloak to go through in order to help fix desyncs */
  443.     if (bit == 1)
  444.     {
  445.     if (sender->level < LEVEL_MODERATOR)
  446.     {
  447.         send_user (sender, MSG_SERVER_NOSUCH,
  448.                "[%s] cloak failed: permission denied", Server_Name);
  449.         if (ISSERVER (con))
  450.         {
  451.         log ("cloak: %s can't cloak, %s desycned", sender->nick,
  452.              con->host);
  453.         /*force a decloak */
  454.         send_cmd (con, MSG_CLIENT_CLOAK, ":%s 0", sender->nick);
  455.         }
  456.         return;
  457.     }
  458.     }
  459.  
  460.     if ((bit == 1 && sender->cloaked) || (bit == 0 && !sender->cloaked))
  461.     return;            /*no change */
  462.  
  463.     sender->cloaked = bit;
  464.  
  465.     /* always send the absolute state when passing server messages */
  466.     pass_message_args (con, tag, ":%s %d", sender->nick, bit);
  467.  
  468.     notify_mods (CLOAKLOG_MODE, "%s has %scloaked", sender->nick,
  469.          sender->cloaked ? "" : "de");
  470.  
  471.     if (ISUSER (con))
  472.     send_cmd (con, MSG_SERVER_NOSUCH, "You are %s cloaked.",
  473.           sender->cloaked ? "now" : "no longer");
  474. }
  475.